﻿using System;
using System.Collections.Generic;
using Ur;
using Sargon;

using Pixels.Logic;
using Pixels.Interface;

namespace Pixels.Rendering
{
    public class WorldRenderer : Sargon.State
    {
        public Camera camera;

        public WorldRenderer() {
            camera = new Camera();
            register_method(Trigger.frame, frame);
            register_method(Trigger.pre_frame, input);
        }

        public Canvas baseCanvas = new Canvas(0f);

        public Tile hilitTile;

        void frame()
        {

            hilitTile = null;

            var cwc = camera.unproject(Mouse.coords);

            if (Interface.Interface.Instance.hilitElement == null) {

                hilitTile = World.Map[cwc.x.myfloor(), cwc.y.myfloor()];
            }

            baseCanvas.doSort = true;

            bool doCull = false;

            Render.canvas = baseCanvas;

            int left = 0, top = 0, right = 0, bottom = 0;

            var bottomRightWorld = camera.unproject(new crds2(0, 0));
            var topLeftWorld = camera.unproject(new crds2(Screen.w, Screen.h));

            if (doCull)
            {
                left = topLeftWorld.x.myfloor();
                top = topLeftWorld.y.myfloor();
                right = bottomRightWorld.x.myfloor() + 1;
                bottom = bottomRightWorld.y.myfloor() + 1;

                left = left.choke(0, World.Map.Width - 1);
                right = right.choke(0, World.Map.Width - 1);


            }
            else
            {
                left = 0; top = 0;
                right = World.Map.Width - 1;
                bottom = World.Map.Height - 1;
            }

            top = top.choke(0, World.Map.Height - 1);
            bottom = bottom.choke(0, World.Map.Height - 1);

            for (var iy = top; iy <= bottom; iy++)
                for (var ix = left; ix <= right; ix++) {
                    var tile = World.Map[ix, iy];
                    var sc = camera.project(tile.worldCenter);


                    if (tile.visibility == Visibility.dark) continue;

                    var textureID = "diamond";
                    var tt = GlobalConsts.getTerrainConsts(tile.Type).tileTextures;
                    //if (tt != null && tt.Length > 0) //textureID = tt[0];
                    textureID = tile.Type.ToString();// StructureOnTile.MyType.ToString();


                    var spr = Render.sprite(textureID, sc, camera.zoom, true);
                    if (textureID != "rocks")
                        spr.overrideOrigin(0.5f, 0.75f);
                    spr.zed = tile.worldCenter.y - tile.worldCenter.x;
                    spr.color = new Color(1, 1, 1, 1f);
                    if (tile.visibility == Visibility.discoverable) {
                        spr.color = new Color(0.2f, 0.2f, 0.2f, 1f);
                    }

                    if (tile == hilitTile) {
                        var reticle = Render.sprite("reticle", sc, camera.zoom, true);
                        reticle.zed = 200;
                    }
                    //if (tile == hilitTile) spr.color = Color.white;
                    if (tile.HasStructure) {
                        if (tile.StructureOnTile != null) {
                            textureID = tile.StructureOnTile.MyType.ToString();
                            var spr2 = Render.sprite(textureID, sc, camera.zoom, true);
                            spr2.overrideOrigin(0.5f, 0.75f);
                            spr2.color = new Color(1, 1, 1, 1f);
                            spr2.zed = 10f + tile.worldCenter.y - tile.worldCenter.x + 0.5f;
                        }
                    }
                }
      
            
        }

        //var txt = Render.text(cwc.print, new crds2(300, 300), temporary: true);


        bool canBuild(Logic.StructureType type) {
            return World.Colony.accumulatedResources.hasEnough(GlobalConsts.getStructureConsts(type).constructionCost);
        }

        void doBuild(Logic.StructureType type) {            
            World.Colony.accumulatedResources.subtractCost(GlobalConsts.getStructureConsts(type).constructionCost);
        }

        void input() {

            Tile hilitTile = null;
            var cwc = camera.unproject(Mouse.coords);
            hilitTile = World.Map[cwc.x.myfloor(), cwc.y.myfloor()];      

            if (Keys.Mouse1.pressed()) {            {
                

                if (Interface.Interface.Instance.hilitElement == null)
                {

                                 
                    if (hilitTile != null) {
                        if (hilitTile.visibility == Visibility.visible) {
                            if (!hilitTile.HasStructure && hilitTile.Type != TerrainType.crystals) {
                                var buildCloseBtn = new Button("", 600 - 40, 8, 32, 32);
                                buildCloseBtn.attachToParent(Interface.Interface.Instance.buildWindow);
                                buildCloseBtn.color = new Color(0, 0, 0, 0);
                                buildCloseBtn.Click += delegate {
                                    foreach (var child in Interface.Interface.Instance.buildWindow.children.ToArray()) if (child is Button) child.die();
                                    Interface.Interface.Instance.buildWindow.hide();
                                };

                                if (hilitTile.Type == TerrainType.fertile)
                                {
                                    var buildBtnX = 30;
                                    var buildBtnY = 50;
                                    var buildText = "Farm";
                                    var btn = new Button(buildText, buildBtnX, buildBtnY, 128, 128);
                                    btn.textureID = "hydroponicFarm";
                                    btn.color = Color.white;
                                    btn.attachToParent(Interface.Interface.Instance.buildWindow);
                                    btn.Click += delegate {
                                        if (canBuild(StructureType.hydroponicFarm)) doBuild(StructureType.hydroponicFarm); else return;
                                        var conSite = (Logic.Structures.ConstructionSite)World.Colony.spawnStructure(StructureType.constructionSite, hilitTile.x, hilitTile.y);
                                        conSite.eventualType = StructureType.hydroponicFarm;
                                        hilitTile.changeType(TerrainType.rocks);
                                        foreach (var child in Interface.Interface.Instance.buildWindow.children.ToArray()) if (child is Button) child.die();
                                        Interface.Interface.Instance.buildWindow.hide();
                                    };

                                    Interface.Interface.Instance.buildWindow.show();
                                }

                                if (hilitTile.Type == TerrainType.rocks)
                                {
                                    var buildBtnX = 30;
                                    var buildBtnY = 50;
                                    var buildText = "Technoforge";
                                    var btn = new Button(buildText, buildBtnX, buildBtnY, 128, 128);
                                    btn.textureID = "technoForge";
                                    btn.attachToParent(Interface.Interface.Instance.buildWindow);
                                    btn.color = Color.white;
                                    btn.Click += delegate
                                    {
                                        if (canBuild(StructureType.technoForge)) doBuild(StructureType.technoForge); else return;
                                        var conSite = (Logic.Structures.ConstructionSite)World.Colony.spawnStructure(StructureType.constructionSite, hilitTile.x, hilitTile.y);
                                        conSite.eventualType = StructureType.technoForge;
                                        foreach (var child in Interface.Interface.Instance.buildWindow.children.ToArray()) if (child is Button) child.die();                                        
                                        Interface.Interface.Instance.buildWindow.hide();
                                    };
                                    buildBtnX += 200;

                                    buildText = "Solar Collector";
                                    btn = new Button(buildText, buildBtnX, buildBtnY, 128, 128);
                                    btn.textureID = "solarCollector";
                                    btn.color = Color.white;
                                    btn.attachToParent(Interface.Interface.Instance.buildWindow);
                                    btn.Click += delegate
                                    {
                                        if (canBuild(StructureType.solarCollector)) doBuild(StructureType.solarCollector); else return;
                                        var conSite = (Logic.Structures.ConstructionSite)World.Colony.spawnStructure(StructureType.constructionSite, hilitTile.x, hilitTile.y);
                                        conSite.eventualType = StructureType.solarCollector;
                                        foreach (var child in Interface.Interface.Instance.buildWindow.children.ToArray()) if (child is Button) child.die();
                                        Interface.Interface.Instance.buildWindow.hide();
                                    };
                                    buildBtnX += 200;

                                    buildText = "Habitat Module";
                                    btn = new Button(buildText, buildBtnX, buildBtnY, 128, 128);
                                    btn.color = Color.white;
                                    btn.textureID = "habitatModule";
                                    btn.attachToParent(Interface.Interface.Instance.buildWindow);
                                    btn.Click += delegate
                                    {
                                        if (canBuild(StructureType.habitatModule)) doBuild(StructureType.habitatModule); else return;
                                        var conSite = (Logic.Structures.ConstructionSite)World.Colony.spawnStructure(StructureType.constructionSite, hilitTile.x, hilitTile.y);
                                        conSite.eventualType = StructureType.habitatModule;
                                        foreach (var child in Interface.Interface.Instance.buildWindow.children.ToArray()) if (child is Button) child.die();
                                        Interface.Interface.Instance.buildWindow.hide();
                                    };
                                    buildBtnY += 220;
                                    buildBtnX = 30;                                    

                                    buildText = "Laboratory";
                                    btn = new Button(buildText, buildBtnX, buildBtnY, 128, 128);
                                    btn.color = Color.white;
                                    btn.textureID = "laboratory";
                                    btn.attachToParent(Interface.Interface.Instance.buildWindow);
                                    btn.Click += delegate
                                    {
                                        if (canBuild(StructureType.laboratory)) doBuild(StructureType.laboratory); else return;
                                        var conSite = (Logic.Structures.ConstructionSite)World.Colony.spawnStructure(StructureType.constructionSite, hilitTile.x, hilitTile.y);
                                        conSite.eventualType = StructureType.laboratory;
                                        foreach (var child in Interface.Interface.Instance.buildWindow.children.ToArray()) if (child is Button) child.die();
                                        Interface.Interface.Instance.buildWindow.hide();
                                    };
                                    buildBtnX += 200;                                    
                                    
                                    buildText = "Nuclear Reactor";
                                    btn = new Button(buildText, buildBtnX, buildBtnY, 128, 128);
                                    btn.textureID = "nuclearReactor";
                                    btn.color = Color.white;
                                    
                                    btn.attachToParent(Interface.Interface.Instance.buildWindow);
                                    btn.Click += delegate
                                    {
                                        if (canBuild(StructureType.nuclearReactor)) doBuild(StructureType.nuclearReactor); else return;
                                        var conSite = (Logic.Structures.ConstructionSite)World.Colony.spawnStructure(StructureType.constructionSite, hilitTile.x, hilitTile.y);
                                        conSite.eventualType = StructureType.nuclearReactor;
                                        foreach (var child in Interface.Interface.Instance.buildWindow.children.ToArray()) if (child is Button) child.die();
                                        Interface.Interface.Instance.buildWindow.hide();
                                    };
                                    buildBtnX += 200;

                                    
                                    buildText = "Antenna";
                                    btn = new Button(buildText, buildBtnX, buildBtnY, 128, 128);
                                    btn.textureID = "antenna";
                                    btn.color = Color.white;
                                    btn.attachToParent(Interface.Interface.Instance.buildWindow);
                                    btn.Click += delegate
                                    {
                                        if (canBuild(StructureType.antenna)) doBuild(StructureType.antenna); else return;
                                        var conSite = (Logic.Structures.ConstructionSite)World.Colony.spawnStructure(StructureType.constructionSite, hilitTile.x, hilitTile.y);
                                        conSite.eventualType = StructureType.antenna;
                                        foreach (var child in Interface.Interface.Instance.buildWindow.children.ToArray()) if (child is Button) child.die();
                                        Interface.Interface.Instance.buildWindow.hide();
                                    };
                                    buildBtnX += 200;

                                    Interface.Interface.Instance.buildWindow.show();
                                }
                            }                                
                        }
                    }
                }
            }

            } 
            if (hilitTile != null && Interface.Interface.Instance.hilitElement == null) {
                Interface.Interface.tooltip = World.generateTooltipForTile(hilitTile);
            }

            if (Interface.Interface.Instance.hilitElement != null) return;

            if (Keys.Mouse2.held()) {
                var prevWC = camera.unproject( Mouse.coords - Mouse.delta);
                var currentWC = camera.unproject( Mouse.coords);
                var deltaWC = prevWC - currentWC;
                camera.coords = camera.target = camera.target + deltaWC;      
                
            }




            //Old zoom
            /*
            if (Mouse.wheel != 0) {
                camera.zoom += Mouse.wheel * 0.1f;
                if (camera.zoom > camera.maxZoom) camera.zoom = camera.maxZoom;
                if (camera.zoom < camera.minZoom) camera.zoom = camera.minZoom;
            }
            */

            //Smooth zoom
            if (Mouse.wheel != 0)
            {
                camera.zoomGoal += Mouse.wheel * 0.1f;
                if (camera.zoomGoal > camera.maxZoom) camera.zoomGoal = camera.maxZoom;
                if (camera.zoomGoal < camera.minZoom) camera.zoomGoal = camera.minZoom;

                //camera.zoom = camera.zoomGoal;

            }
            //Zoom acceleration
            if (camera.zoom > camera.zoomGoal) camera.zoom -= 4f * Game.frame_time * Math.Abs(camera.zoom - camera.zoomGoal);
            if (camera.zoom < camera.zoomGoal) camera.zoom += 4f * Game.frame_time * Math.Abs(camera.zoom - camera.zoomGoal);









            //TODO - Slay like right click for solider

            if (Keys.Mouse3.pressed())
            {
                Dictionary<int, PeopleDragger.PeopleIcon> peopleIcons = new Dictionary<int, PeopleDragger.PeopleIcon>();

                var l = new List<Colonist>(World.Colony.idleColonists);
                l.Sort();
                int counter = 0;
                try { 
                foreach (var cc in l) {
                    peopleIcons[cc.uniqueID].updateAsIdle(counter);
                    counter++;
                    }
                }
                catch { }


                PeopleDragger drag = World.pd;// new PeopleDragger(this);

                if (drag.hilitIcon != null)
                { 
                foreach (var icon in peopleIcons.Values)
                    drag.hilitIcon = icon;
                drag.startDrag(drag.hilitIcon);
                }
            }

            if (Keys.Mouse3.released())
            {
                //PeopleDragger drag = new PeopleDragger(this);
                World.pd.releaseDrag();
            }



        }
        

        void renderTile(Tile t) {
            camera.project(t.worldCenter);
        }
    }
}
